package section3_5;

import java.util.concurrent.CyclicBarrier;

/**
 * Created by Hyman on 2017/6/4.
 *
 * 在集合点的同步
 *
 * 虽然CyclicBarrier类和CountDowmLatch类有很多共性，但是它们也有一定的差异。
 * 其中最重要的不同是，CyclicBarrier对象可以被重置回初始状态，并把它的内部计数器重置成初始化时的值
 *
 *  CyclicBarrier初始化时规定一个数目，然后计算调用了CyclicBarrier.await()进入等待的线程数。当线程数达到了这个数目时，所有进入等待状态的线程被唤醒并继续。
 *  CyclicBarrier就象它名字的意思一样，可看成是个障碍， 所有的线程必须到齐后才能一起通过这个障碍。
 *  CyclicBarrier初始时还可带一个Runnable的参数， 此Runnable任务在CyclicBarrier的数目达到后，所有其它线程被唤醒前被执行。
 */
public class Main {

    public static void main(String[] args) {

        final int ROWS = 10000; // 矩阵的行数
        final int NUMBERS = 1000; // 矩阵的列数
        final int SEARCH = 5;   // 要查询的数字
        final int PARTICIPANTS = 5; // 查询线程的个数
        final int LINES_PARTICIPANT = 2000; // 每个查询线程处理的行数

        MatrixMock mock = new MatrixMock(ROWS, NUMBERS, SEARCH);
        Results results = new Results(ROWS);
        Grouper grouper = new Grouper(results);

        // 创建一个同步栅对象，它有5个参与者， 5个参与者线程完成后，会调用grouper中的run方法
        CyclicBarrier barrier = new CyclicBarrier(PARTICIPANTS, grouper);

        // 创建5个参与者对象，并且让它们各自在单独的线程中运行
        Searcher[] searchers = new Searcher[PARTICIPANTS];

        for(int i=0; i<searchers.length; i++) {
            searchers[i] = new Searcher(i*LINES_PARTICIPANT,
                    i*LINES_PARTICIPANT+LINES_PARTICIPANT, mock, results, SEARCH, barrier);
            Thread thread = new Thread(searchers[i]);
            thread.start();
        }

        System.out.printf("Main: The main thread has finished.\n");
    }

}
